; 实验10 编写子程序
; 显示字符串
; 编写一个通用的子程序来实现字符串显示功能，调用者可指定显示位置(行 列) 内容 颜色
; show_str,字符串用0结束 (dh)指定行号 (dl)指定列号 (cl)指定颜色 ds:[si]指向字符串首地址
assume cs:codesg
datasg segment
    db '0123456701234567'0
datasg ends
stacksg segment
    dw 16 dup(0)
stacksg ends

codesg segment
start:
            mov dh,8
            mov dl,3
            mov cl,2
            mov ax,data
            mov ds,ax
            mov si,0
            mov ax,stacksg
            mov ss,ax
            mov sp,10h

            call show_str

            mov ax,4c00h
            int 21h
show_str:
            push ax
            push bx
            push cx
            push dx
            push si
            push ds
            push es

            mov es,0B800h
            ; 首先判断行号列号不超出范围，0<=行号<=24 ,0<=列号<=79
            mov ax,10h
            mul dh
            mov bx ax ;存储行号结果
            mov ax,2h 
            mul dl
            add bx,ax
            mov dl,cl
            ; 组合样式
    s:      
            mov byte ptr cl,ds:[si]
            mov ch,0
            jcxz end
            mov es:[bx],cl
            mov es:[bx+1],dl
            inc si
            add bx,2
            loop s
end:        
            pop es
            pop ds
            pop si
            pop dx
            pop cx
            pop bx
            pop ax
            ret

codesg ends

; 解决除法溢出问题
; 结果的商大于al或者ax所能存储的最大值
; 使用子程序解决除法溢出问题divdw,被除数dword,除数word,结果为dword
; 参数：(ax)=dword数据类型的低16位，(dx)=dword数据类型的高16位,(cx)=除数
; 返回:(dx)=dword商高16位，(ax)=dword商低16位，(cx)=余数
; 提示：公式：X/N = int(H/N)*65536 + [rem(H/N)*65536+L]/N 

datasg2 segment
    dw 8 dup(0)
datasg2 ends

codesg2 segment
start2:
        mov ax,4240h
        mov dx,000Fh
        mov cx,0Ah
        call divdw
        ; 结果(dx)=0001H,(ax)=85A0H,(cx)=0
divdw:  
        push ds
        push bx
        push bp
        push si
        push di
        jcxz end
        mov bx,datasg2
        mov ds,bx
        ; 存储参数值
        mov ds:[0],ax
        mov ds:[2],dx
        mov ds:[4],cx
        ; 计算H/N
        mov ax,dx
        mov dx,0
        div cx
        ; 存储结果H/N
        mov ds:[6],ax
        mov ds:[8],dx
        ; 计算 int(H/N)*65536
        mul word ptr 65536
        mov ds:[10],ax
        mov ds:[12],dx
        ; 计算 [rem(h/N)*65536+L]/N
        mov ax,ds:[8]
        mul 65536
        add ax,ds:[0]
        div word ptr ds:[4]
        add ds:[6],ax
        ; 传出结果
        mov cx,dx
        mov ax,ds:[6]
        mov dx,ds:[8]
end:    
        push di
        push si
        pop bp
        pop bx
        pop ds
        ret

codesg2 ends

; 数值显示
; 将data数据段中的数据以十进制显示
; 

datasg3 segment
        dw 123,12666,1,8,3,38
datasg3 ends

codesg3 segment

codesg3 ends

end start
